"""
写入接口实现模块
================

该模块整合各功能模块，实现完整的write函数功能。
"""
from typing import Any, Dict, List, Union, Optional, Tuple
from .param_parser import ParamParser
from .address_resolver import AddressResolver
from .config_manager import ConfigManager
from .data_validator import DataValidator
from .callback_manager import CallbackManager
from .typedef import FullWriteType, AddressType, ValueType, PreProcessorType, PostProcessorType,DataType
from .write_interface import WriteInterface
from ..utils.logger import get_logger,default_logger
from ..core.communication_interface import CommunicationInterface


class WriteInterfaceWrapper:
    """写入接口实现类"""

    @staticmethod
    def write(comm: CommunicationInterface,
              address: FullWriteType,
              value: Optional[Any] = None,
              *args: Any,
              data_type: Optional[Union[str, DataType, List[Union[str, DataType]]]] = None,
              timeout: Optional[Union[int, float]] = None,
              sync: Optional[bool] = None,
              confirm: Optional[bool] = None,
              retry: Optional[int] = None,
              raise_on_error: Optional[bool] = None,
              quality_check: Optional[bool] = None,
              preprocessors: Optional[List[PreProcessorType]] = None,
              postprocessors: Optional[List[PostProcessorType]] = None,
              batch_size: Optional[int] = None,
              transaction: Optional[bool] = None,
              **kwargs: Any) -> Union[
                  bool,                    # single write result
                  Dict[Any, bool],         # batch write results
                  Dict[str, Any]           # config write results
              ]:
        """
        实现写入接口

        Args:
            address: 写入地址
            value: 写入值
            *args: 位置参数
            data_type: 数据类型，支持单个值或列表
            timeout: 超时时间
            sync: 同步模式
            confirm: 确认模式
            retry: 重试次数
            raise_on_error: 出错时是否抛出异常
            quality_check: 质量检查
            preprocessors: 预处理器列表
            postprocessors: 后处理器列表
            batch_size: 批量大小
            transaction: 事务模式
            **kwargs: 关键字参数

        Returns:
            写入结果
        """
        logger = default_logger.getChild("WriteInterfaceWrapper")
        logger.info(f"开始执行写入操作: address={address}, value={value}")

        try:
            # 1. 解析参数
            parsed_params = ParamParser.parse_write_address(address)
            logger.debug(f"地址参数解析完成: {parsed_params}")

            # 解析位置参数和关键字参数
            pos_config = ParamParser.parse_positional_args(*args)
            kw_config = ParamParser.parse_keyword_args(**kwargs)
            merged_config = ParamParser.merge_configs(pos_config, kw_config)
            logger.debug(f"配置参数解析完成: 位置参数={pos_config}, 关键字参数={kw_config}, 合并配置={merged_config}")

            # 如果提供了value且地址不是元组/列表/字典，则构造(address, value)元组并重新解析
            if value is not None and not isinstance(address, (tuple, list, dict)):
                logger.debug("构造(address, value)元组并重新解析")
                parsed_params = ParamParser.parse_write_address((address, value))
            elif value is not None and isinstance(address, dict):
                # 如果地址是字典且提供了value，将value添加到地址信息中
                logger.debug("将value添加到字典地址信息中")
                parsed_params['values'] = [value]
            elif value is not None and isinstance(address, (list, tuple)):
                # 如果地址是列表或元组，且提供了value，则根据value的类型进行处理
                logger.debug("处理列表/元组地址和value参数")
                # 如果value也是列表或元组，可能表示批量写入
                if isinstance(value, (list, tuple)):
                    # 构造一个包含addresses和values的字典
                    new_address = {
                        'addresses': list(address),
                        'values': list(value)
                    }
                    parsed_params = ParamParser.parse_write_address(new_address)
                # 如果value是字典，可能包含额外的配置信息
                elif isinstance(value, dict):
                    # 将address作为地址，value作为配置
                    new_address = {'address': address}
                    new_address.update(value)
                    parsed_params = ParamParser.parse_write_address(new_address)
                else:
                    # 其他情况，将value作为单个值处理
                    parsed_params['values'] = [value]

            # 2. 解析地址
            address_type = parsed_params.get('address_type', 'single')
            logger.debug(f"开始解析地址类型: {address_type}")

            try:
                if address_type == 'single':
                    address_info = AddressResolver.resolve_write_address(parsed_params.get('addresses')[0])
                elif address_type == 'batch':
                    address_info = AddressResolver.resolve_write_address(parsed_params.get('addresses'))
                elif address_type == 'config':
                    address_info = AddressResolver.resolve_write_address(address)
                else:
                    address_info = AddressResolver.resolve_write_address(parsed_params.get('addresses')[0])

                # 将解析出的值、数据类型、选项和长度信息合并到address_info中
                if 'values' in parsed_params and parsed_params['values']:
                    address_info['values'] = parsed_params['values']
                if 'data_types' in parsed_params and parsed_params['data_types']:
                    address_info['data_types'] = parsed_params['data_types']
                if 'options' in parsed_params and parsed_params['options']:
                    address_info['options'] = parsed_params['options']
                if 'lengths' in parsed_params and parsed_params['lengths']:
                    address_info['lengths'] = parsed_params['lengths']

                logger.debug(f"地址解析完成: {address_info}")
            except Exception as e:
                error_msg = f"地址解析失败: {str(e)}"
                logger.error(error_msg, exc_info=True)
                raise ValueError(f"dizhi解析失败: {str(e)}")

            # 3. 处理配置
            # 更新配置管理器
            logger.debug("开始更新配置管理器")
            try:
                # 获取当前配置
                config = ConfigManager.create_default_config()

                if 'timeout' in merged_config:
                    config = ConfigManager.set_timeout(config, merged_config['timeout'])
                if 'data_type' in merged_config:#处理为类型
                    # config = ConfigManager.set_data_type(config, merged_config['data_type'])
                    address_info['data_types'] = merged_config['data_type']
                if 'sync' in merged_config:
                    config = ConfigManager.set_sync_mode(config, merged_config['sync'])
                if 'confirm' in merged_config:
                    config = ConfigManager.set_confirmation(config, merged_config['confirm'])
                if 'retry' in merged_config:
                    config = ConfigManager.set_retry_count(config, merged_config['retry'])
                if 'raise_on_error' in merged_config:
                    config = ConfigManager.set_error_handling(config, merged_config['raise_on_error'])
                if 'quality_check' in merged_config:
                    config = ConfigManager.set_quality_check(config, merged_config['quality_check'])
                if 'preprocessors' in merged_config:
                    config = ConfigManager.set_preprocessors(config, merged_config['preprocessors'])
                if 'postprocessors' in merged_config:
                    config = ConfigManager.set_postprocessors(config, merged_config['postprocessors'])
                if 'batch_size' in merged_config:
                    config = ConfigManager.set_batch_size(config, merged_config['batch_size'])
                if 'transaction' in merged_config:
                    config = ConfigManager.set_transaction(config, merged_config['transaction'])

                # 移除data_type和data_types字段，不向下传递
                if 'data_type' in config:
                    config.pop('data_type')
                if 'data_types' in config:
                    config.pop('data_types')

                logger.debug(f"配置更新完成: {config}")
                logger.debug(f"配置更新完成: {config}")
            except Exception as e:
                error_msg = f"配置处理失败: {str(e)}"
                logger.error(error_msg, exc_info=True)
                raise ValueError(f"配置处理失败: {str(e)}")

            # 4. 验证数据
            logger.debug("开始验证数据")
            try:
                validation_result = DataValidator.validate_write_all(address_info, config)
                if not validation_result.get('valid', True):
                    error_msg = validation_result.get('error', 'Data validation failed')
                    logger.warning(f"数据验证失败: {error_msg}")
                    return False
                logger.debug("数据验证通过")
            except Exception as e:
                error_msg = f"数据验证过程中发生错误: {str(e)}"
                logger.error(error_msg, exc_info=True)
                return False


            # 6. 执行写入
            logger.debug("开始执行写入操作")
            write_results = {}
            try:
                if address_type == 'single':
                    # 单个写入
                    addr = address_info.get('addresses')[0]
                    val = address_info.get('values')[0] if address_info.get('values') else None
                    data_type = address_info.get('data_types') if address_info.get('data_types') else None
                    write_result = comm.write_register(addr, val, data_type,**config)
                    write_results = {addr: write_result}
                elif address_type == 'batch':
                    # 批量写入，构造batch_data字典形式
                    addresses = address_info.get('addresses', [])
                    values = address_info.get('values', [])
                    data_types = address_info.get('data_types', [])

                    # 构造batch_data字典形式 {"address": {"value": value, "data_type": data_type}}
                    batch_data = {}
                    for i, addr in enumerate(addresses):
                        if i < len(values):
                            if i < len(data_types):
                                batch_data[addr] = {"value": values[i], "data_type": data_types[i]}
                            else:
                                batch_data[addr] = values[i]
                        else:
                            batch_data[addr] = {"value": None}

                    # 调用write_batch方法，只传递data参数和关键字参数
                    write_results = comm.send_data(batch_data, **config)
                elif address_type == 'config':
                    # 配置写入
                    if "address" in address:
                        addr = address["address"]
                        val = address["value"] if "value" in address else None
                        data_type = address["data_type"] if "data_type" in address else None
                        write_result = comm.write_register(addr, val, data_type,**config)
                        write_results = {addr: write_result}
                    else:
                        # 批量写入，构造batch_data字典形式
                        addresses = address_info.get('addresses', [])
                        values = address_info.get('values', [])
                        data_types = address_info.get('data_types', [])

                        # 构造batch_data字典形式 {"address": {"value": value, "data_type": data_type}}
                        batch_data = {}
                        for i, addr in enumerate(addresses):
                            value_data ={}
                            if i < len(values):
                                value_data["value"] = values[i]
                                if i < len(data_types):
                                    value_data["data_type"] = data_types[i]
                                batch_data[addr] = value_data
                            else:
                                batch_data[addr] = {"value": None}

                        # 调用write_batch方法，只传递data参数和关键字参数
                        write_results = comm.send_data(batch_data, **config)
                else:
                    # 默认单个写入
                    addr = address_info.get('addresses')[0]
                    val = address_info.get('values')[0] if address_info.get('values') else None
                    write_result = comm.write(addr, val, config['data_type'])
                    write_results = {addr: write_result}
                logger.debug(f"写入操作执行完成: {write_results}")
            except Exception as e:
                error_msg = f"执行写入操作时出错: {str(e)}"
                logger.error(error_msg, exc_info=True)
                raise ValueError(f"执行写入操作时出错: {str(e)}")

            # 7. 处理结果
            logger.debug("开始处理写入结果")
            return write_results

        except Exception as e:
            raise ValueError(f"写入操作过程中发生未预期的错误: {str(e)}")

